﻿Imports Microsoft.VisualBasic
Imports Microsoft.Practices.EnterpriseLibrary.Logging

Public Class General
    Const Category As String = "General"
    ''' <summary>
    ''' Create Hash of given String
    ''' </summary>
    ''' <param name="stringToEncrypt"></param>
    ''' <returns></returns>
    ''' <remarks>http://support.microsoft.com/kb/301053</remarks>
    Public Shared Function EncryptStringToHash(ByVal stringToEncrypt As String) As String
        Dim tmpSource() As Byte
        Dim tmpHash() As Byte
        tmpSource = System.Text.ASCIIEncoding.ASCII.GetBytes(stringToEncrypt)
        tmpHash = New System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(tmpSource)
        Dim i As Integer
        Dim sOutput As New Text.StringBuilder(tmpHash.Length)
        For i = 0 To tmpHash.Length - 1
            sOutput.Append(tmpHash(i).ToString("X2"))
        Next
        Return sOutput.ToString()
    End Function

    Public Shared Function CreateLogProperties(ByVal username As String) As Dictionary(Of String, Object)
        CreateLogProperties = New Dictionary(Of String, Object)
        CreateLogProperties.Add("User", username)
    End Function


    ''' <summary>
    ''' Check whether FTP-Upload is enabled for given project
    ''' </summary>
    ''' <param name="project"></param>
    ''' <param name="logProperties"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function FTPUploadEnabled(ByVal project As String, ByVal logProperties As Dictionary(Of String, Object)) As Boolean
        Const LogTitle As String = "FTPUploadEnabled"
        Logger.Write(LogTitle & " -> Start [Project: '" & project & "'].", Category, 10, 0, Diagnostics.TraceEventType.Start, LogTitle, logProperties)
        Dim Filename As String = ConfigurationManager.AppSettings("ProjectDirectory").ToString & project & ".xml"
        If IO.File.Exists(Filename) Then
            Logger.Write("Project file '" & Filename & "' found.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
            Dim ProjectFile As System.Xml.XmlDocument = XMLFile.GetXMLDocument(Filename)
            If ProjectFile.SelectNodes("/project/ftp/server").Count = 0 Then
                Logger.Write("No FTP-Server defined.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                FTPUploadEnabled = False
            Else
                Logger.Write(ProjectFile.SelectNodes("/project/ftp/server").Count.ToString & " ftp-connections for project '" & project & "' found.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                FTPUploadEnabled = True
            End If
        Else
            Logger.Write("Project file '" & Filename & "' not found.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
            FTPUploadEnabled = False
        End If
        Logger.Write(LogTitle & " -> End [Project: '" & project & "']: " & FTPUploadEnabled.ToString, Category, 10, 0, Diagnostics.TraceEventType.Stop, LogTitle, logProperties)
    End Function

    ''' <summary>
    ''' Upload file to FTP Server
    ''' </summary>
    ''' <param name="project"></param>
    ''' <param name="fullfilename">Full Filepath including filename</param>
    ''' <param name="logProperties"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function FTPUpload(ByVal project As String, ByVal fullFilename As String, ByVal logProperties As Dictionary(Of String, Object)) As Boolean
        Const LogTitle As String = "FTPUpload"
        FTPUpload = False
        Logger.Write(LogTitle & " -> Start [Project: '" & project & "' - Filename: '" & fullFilename & "'].", Category, 10, 0, Diagnostics.TraceEventType.Start, LogTitle, logProperties)
        Dim XMLFilename As String = ConfigurationManager.AppSettings("ProjectDirectory").ToString & project & ".xml"
        Dim ProjectFile As System.Xml.XmlDocument = XMLFile.GetXMLDocument(XMLFilename)
        Dim FTPNode As System.Xml.XmlNode
        Dim Language As String = fullFilename.Split(".".ToCharArray)(fullFilename.Split(".".ToCharArray).GetUpperBound(0) - 1)
        Dim Filename As String = fullFilename.Split("\".ToCharArray)(fullFilename.Split("\".ToCharArray).GetUpperBound(0))
        Logger.Write("File '" & Filename & "' belongs to language '" & Language & "'.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
        For Each FTPNode In ProjectFile.SelectNodes("/project/ftp")

            If FTPNode.SelectSingleNode("server") Is Nothing Then
                Logger.Write("FTP-Server-Node not found.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
            Else
                Dim Servername As String = FTPNode.SelectSingleNode("server").InnerText
                If Servername.Length = 0 Then
                    Logger.Write("FTP-Server is not defined.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                Else
                    Logger.Write("Processing Upload to FTP-Server '" & Servername & "'.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                    Dim UploadPath As String = FTPNode.SelectSingleNode("path").InnerText
                    If UploadPath.Length > 0 Then
                        If InStr(UploadPath, "%LANG%") > 0 Then
                            UploadPath = Replace(UploadPath, "%LANG%", Language)
                        End If
                        If Right$(UploadPath, 1) <> "/" Then
                            UploadPath &= "/"
                        End If
                    Else
                        UploadPath = "/"
                    End If
                    Dim Username As String = FTPNode.SelectSingleNode("username").InnerText
                    Dim Password As String = FTPNode.SelectSingleNode("password").InnerText
                    Dim myFtp As New FTP.FTPclient(Servername, Username, Password)
                    Dim ExistingFiles As List(Of String)
                    'First check whether directory is accessable
                    Try
                        ExistingFiles = myFtp.ListDirectory(UploadPath)
                    Catch ex As Exception
                        Logger.Write("Probably FTP-Directory (" & UploadPath & ") does not exist. " & ex.Message)
                        myFtp.FtpCreateDirectory(UploadPath)
                        ExistingFiles = myFtp.ListDirectory(UploadPath)
                    End Try

                    If ExistingFiles.Contains(Filename) Then
                        Logger.Write("File '" & Filename & "' already existing in target FTP path. Deleting existing file.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                        If myFtp.FtpDelete(UploadPath & Filename) Then
                            Logger.Write("File '" & UploadPath & Filename & "' successfully deleted.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                        Else
                            Logger.Write("Error deleting '" & UploadPath & Filename & "'.", Category, 200, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                        End If
                    End If

                    If myFtp.Upload(fullFilename, UploadPath & Filename) Then
                        Logger.Write("Uploaded '" & UploadPath & Filename & "'.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                        FTPUpload = True
                    Else
                        Logger.Write("Error uploading '" & UploadPath & Filename & "'.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                    End If
                End If
            End If
        Next

        Logger.Write(LogTitle & " -> End [Project: '" & project & "' - Filename: '" & filename & "']: " & FTPUpload.ToString, Category, 10, 0, Diagnostics.TraceEventType.Stop, LogTitle, logProperties)

    End Function

    ''' <summary>
    ''' Save current XML File in backup directory
    ''' </summary>
    ''' <param name="xmlDoc">Document to be saved</param>
    ''' <param name="fullFilename">Current filename</param>
    ''' <param name="logProperties"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function CreateBackup(ByVal xmlDoc As System.Xml.XmlDocument, _
                                        ByVal fullFilename As String, ByVal logProperties As Dictionary(Of String, Object)) As Boolean
        Const LogTitle As String = "CreateBackup"
        Const BackupDirectory As String = "Backup"
        Logger.Write(LogTitle & " -> Start [Filename: '" & fullFilename & "']", Category, 10, 0, Diagnostics.TraceEventType.Start, LogTitle, logProperties)
        If xmlDoc Is Nothing Then
            Logger.Write("No XMLDocument supplied. Nothing to do.", Category, 100, 0, Diagnostics.TraceEventType.Information, LogTitle, logProperties)
            CreateBackup = False
        ElseIf fullFilename.Length = 0 Then
            Logger.Write("No Filename supplied. Nothing to do.", Category, 100, 0, Diagnostics.TraceEventType.Information, LogTitle, logProperties)
            CreateBackup = False
        Else
            Dim Filename As String = fullFilename.Split("\".ToCharArray)(fullFilename.Split("\".ToCharArray).GetUpperBound(0))
            Dim FilePath As String = Left$(fullFilename, Len(fullFilename) - Len(Filename)) & BackupDirectory & "\"
            If Not IO.Directory.Exists(FilePath) Then
                Logger.Write("Target directory '" & FilePath & "' does not exist.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                If IO.Directory.CreateDirectory(FilePath).Exists Then
                    Logger.Write("New backup directory '" & FilePath & "' created successfully.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                Else
                    Logger.Write("Error creating backup directory '" & FilePath & "'.", Category, 300, 0, Diagnostics.TraceEventType.Error, LogTitle, logProperties)
                    CreateBackup = False
                End If
            End If
            If IO.Directory.Exists(FilePath) Then
                Filename &= "." & Format(Now, "yyyyMMdd-HHmmssffff") & ".bak"
                Logger.Write("Saving backup to '" & Filename & "'.", Category, 10, 0, Diagnostics.TraceEventType.Verbose, LogTitle, logProperties)
                xmlDoc.Save(FilePath & Filename)
                If IO.File.Exists(FilePath & Filename) Then
                    Logger.Write("Saved backup to '" & FilePath & Filename & "' successfully.", Category, 100, 0, Diagnostics.TraceEventType.Information, LogTitle, logProperties)
                    CreateBackup = True
                Else
                    Logger.Write("Error saving backup to '" & FilePath & Filename & "'.", Category, 200, 0, Diagnostics.TraceEventType.Warning, LogTitle, logProperties)
                    CreateBackup = False
                End If
            End If
        End If
        Logger.Write(LogTitle & " -> End [Filename: '" & fullFilename & "']: " & CreateBackup.ToString, Category, 10, 0, Diagnostics.TraceEventType.Stop, LogTitle, logProperties)

    End Function
End Class
